import * as vscode from 'vscode';

export default class CMD2Lua{
    context : vscode.ExtensionContext = null;
    disposable_read : vscode.Disposable = null;
    disposable_write : vscode.Disposable = null;

    constructor(context : vscode.ExtensionContext){
        this.context = context;
    }
    
    registerCommand(){
        //注册事件
        this.disposable_read = vscode.commands.registerTextEditorCommand('zhaoExtensionTools.CMD2Lua_read', (textEditor, edit) => {
            const doc = textEditor.document;
            let selection: vscode.Selection | vscode.Range = textEditor.selection;
            
            let text = doc.getText(selection);
            if (text === "") {
                vscode.window.showInformationMessage("未选择文本");
                return;
            }
            //替换文件内容
            const replaceStr = this.cmd2LuaRead(text);
            if (replaceStr === "") {
                vscode.window.showErrorMessage("转换失败，请注意格式");
                return;
            }
            textEditor.edit((builder) => {
                builder.replace(selection, replaceStr);
            });
        });

        this.disposable_write = vscode.commands.registerTextEditorCommand('zhaoExtensionTools.CMD2Lua_write', (textEditor, edit) => {
            const doc = textEditor.document;
            let selection: vscode.Selection | vscode.Range = textEditor.selection;
            
            let text = doc.getText(selection);
            if (text === "") {
                vscode.window.showInformationMessage("未选择文本");
                return;
            }
            //替换文件内容
            const replaceStr = this.cmd2LuaWrite(text);
            if (replaceStr === "") {
                vscode.window.showErrorMessage("转换失败，请注意格式");
                return;
            }
            textEditor.edit((builder) => {
                builder.replace(selection, replaceStr);
            });
        });
        this.context.subscriptions.push(this.disposable_read);
        this.context.subscriptions.push(this.disposable_write);
    }
    unRegisterCommand(){

    }

    //前面的注释和结构体名
    processNameString(index : {startIndex : number}, txt : string){
        let startReg = /(?:\s*\/\/(.+)\s*\n)?struct (\S+)\s*\n{?/g;                   //开始的注释
        startReg.lastIndex = index.startIndex;
        let startArray = startReg.exec(txt);
        return startArray;
    }

    //结构体内容
    processContentString(index : {startIndex : number}, txt : string) : Array<any>{
        let reg = /\s*(WORD|DWORD|LONGLONG|BYTE|bool|BOOL|TCHAR|CHAR|int|INT|LONG|float|SCORE|DOUBLE|double|INT64|UINT)\s+(\w+)(?:\[([\w|_]+)\])?;\s*(?:\/\/(.*))?\n?/g;
        reg.lastIndex = index.startIndex;
        let contentArray = [];
        let tempArray = null;
        while((tempArray = reg.exec(txt)) !== null)
        {
            contentArray.push(tempArray);
            index.startIndex = reg.lastIndex;
        }
        return contentArray;
    }

    //结构体结束符};
    processEndString(index : {startIndex : number}, txt : string){
        let endReg = /};/g;
        endReg.lastIndex = index.startIndex;
        let endArray = endReg.exec(txt);
        return endArray;
    }

    cmd2LuaRead(txt : string) : string{
        let startIndex = {startIndex : 0};
        let str_ : string = "";
        let headArray = this.processNameString(startIndex, txt);
        let contentArray = this.processContentString(startIndex, txt);
        let endArray = this.processEndString(startIndex, txt);

        if (headArray) {        //有头部
            if (headArray[1]) {     //有注释
                str_ += "-- " + headArray[1] + "\n";
            }
            if (headArray[2]) {
                str_ += `CMDExt.${headArray[2]} = class("${headArray[2]}",CMDBase)\n`;
                str_ += `function CMDExt.${headArray[2]}:readFormByteArray(ba)\n`;
            }
        }
        for (const array_ of contentArray) {
            let lineStr = "\tself." + array_[2] + "\t=\t\t\tba:read";
            if (array_[1] === "WORD" || array_[1] === "DWORD" || array_[1] === "LONGLONG" || array_[1] === "BYTE") {
                lineStr += array_[1] + "()";
            }else if (array_[1] === "bool") {
                lineStr += "Bool" + "()";
            }else if (array_[1] === "int" || array_[1] === "LONG" || array_[1] === "BOOL" || array_[1] === "INT"){
                lineStr += "Int" + "()";
            }else if (array_[1] === "float") {
                lineStr += "Float" + "()";
            }else if (array_[1] === "SCORE" || array_[1] === "DOUBLE" || array_[1] === "INT64") {
                lineStr += "LONGLONG" + "()";
            }else if (array_[1] === "double") {
                lineStr += "Double" + "()";
            }else if (array_[1] === "UINT") {
                lineStr += "UINT" + "()";
            }else{
                if (isNaN(Number(array_[3])) === true ) {           //非数字
                    lineStr += array_[1] + "(" + "BD." + array_[3] + ")";
                }else{
                    lineStr += array_[1] + "(" + array_[3] + ")";
                }
            }
            lineStr += "\t\t\t" + "--";
            if (array_[4]) {
                lineStr += " " + array_[4];
            }
            lineStr += "\n";
            str_ += lineStr;
        }
        if (endArray) {
            str_ += "end";
        }
        return str_;
    }

    cmd2LuaWrite(txt : string) : string{
        let startIndex = {startIndex : 0};
        let str_ : string = "";
        let headArray = this.processNameString(startIndex, txt);
        let contentArray = this.processContentString(startIndex, txt);
        let endArray = this.processEndString(startIndex, txt);

        if (headArray) {        //有头部
            if (headArray[1]) {     //有注释
                str_ += "-- " + headArray[1] + "\n";
            }
            if (headArray[2]) {
                str_ += `CMDExt.${headArray[2]} = class("${headArray[2]}",CMDBase)\n`;
                str_ += `function CMDExt.${headArray[2]}:writeToByteArray(ba)\n`;
            }
        }
        for (const array_ of contentArray) {
            let lineStr = "\tba:write";
            if (array_[1] === "WORD" || array_[1] === "DWORD" || array_[1] === "LONGLONG" || array_[1] === "BYTE") {
                lineStr += array_[1] + "(self." + array_[2] + ")";
            }else if (array_[1] === "bool") {
                lineStr += "Bool" + "(self." + array_[2] + ")";
            }else if (array_[1] === "int" || array_[1] === "LONG" || array_[1] === "BOOL" || array_[1] === "INT"){
                lineStr += "Int" + "(self." + array_[2] + ")";
            }else if (array_[1] === "float") {
                lineStr += "Float" + "(self." + array_[2] + ")";
            }else if (array_[1] === "SCORE" || array_[1] === "DOUBLE" || array_[1] === "INT64") {
                lineStr += "LONGLONG" + "(self." + array_[2] + ")";
            }else if (array_[1] === "double") {
                lineStr += "Double" + "(self." + array_[2] + ")";
            }else if (array_[1] === "UINT") {
                lineStr += "UINT" + "(self." + array_[2] + ")";
            }else{
                if (isNaN(Number(array_[3])) === true ) {           //非数字
                    lineStr += array_[1]  + "(self." + array_[2] + ",BD." + array_[3] + ")";
                }else{
                    lineStr += array_[1]  + "(self." + array_[2] + "," + array_[3] + ")";
                }
            }
            lineStr += "\t\t\t" + "--";
            if (array_[4]) {
                lineStr += " " + array_[4];
            }
            lineStr += "\n";
            str_ += lineStr;
        }

        if (endArray) {
            str_ += "end";
        }
        return str_;
    }


}